package org.example.quartz.job;

import org.quartz.*;
import org.quartz.impl.matchers.GroupMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 * 
 *
 * @author liuwp
 * @date 2018年12月21日下午4:10:30
 * @version 1.0.0
 */
public class DefaultJobManager implements JobManager {

    private static final Logger logger = LoggerFactory.getLogger(DefaultJobManager.class);
    private final static String JOB_GROUP = "JOB_Y";

    private final Scheduler scheduler;

    public DefaultJobManager(Scheduler scheduler) {
        this.scheduler = scheduler;
    }

    @Override
    public void addJob(String id, String cron, Class<? extends Job> jobclass) throws JobException {
        JobDetail jobDetail = JobBuilder.newJob(jobclass).withIdentity(id, JOB_GROUP).build();
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(id, JOB_GROUP)
                .withSchedule(cronScheduleBuilder).build();
        try {
            scheduler.scheduleJob(jobDetail, cronTrigger);
            scheduler.start();
            logger.info("Add job successfully (id={},cron={},jobclass={})", id, cron, jobclass);
            return;
        } catch(ObjectAlreadyExistsException e){
            logger.warn("Fail to add job(id=" + id + ")", e);
            throw new JobException("job id已存在");
        }catch (SchedulerException e) {
            logger.warn("Fail to add job(id=" + id + ")", e);
            throw new JobException("添加job失败");
        }
    }

    @Override
    public void removeJob(String id) throws JobException {
        JobKey jobKey = new JobKey(id, JOB_GROUP);
        JobDetail jobDetail;
        try {
            jobDetail = scheduler.getJobDetail(jobKey);
        } catch (SchedulerException e) {
            logger.warn("Fail to get job info(id=" + id + ")", e);
            throw new JobException("获取job失败");
        }
        if (jobDetail == null) {
            logger.warn("Id not exsist (id=" + id + ")");
            throw new JobException("job id不存在");
        }
        try {
            scheduler.deleteJob(jobKey);
            logger.info("Delete job successfully (id=" + id + ")");
        } catch (SchedulerException e) {
            logger.warn("Fail to remove Job(id=" + id + ")", e);
            throw new JobException("job 删除失败");
        }
    }

    @Override
    public void modifyJob(String id, String cron) throws JobException {
        TriggerKey triggerKey = new TriggerKey(id, JOB_GROUP);
        CronTrigger cronTrigger;
        try {
            cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        } catch (SchedulerException e) {
            logger.warn("Fail to get trigger (id=" + id + ")", e);
            throw new JobException("获取job失败");
        }
        String oldCron = cronTrigger.getCronExpression();
        if (!oldCron.equalsIgnoreCase(cron)) {
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
            CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(id, JOB_GROUP)
                    .withSchedule(cronScheduleBuilder).build();
            try {
                scheduler.rescheduleJob(triggerKey, trigger);
                logger.info("Modify job successfully(id={},cron={})", id, cron);
            } catch (SchedulerException e) {
                logger.warn("Fail to modify Job(id=" + id + ")", e);
                throw new JobException("修改job失败");
            }
        } else {
            logger.info("Cron not changed and will not modify job(id={},cron={})", id, cron);
        }
    }

    @Override
    public String[] getJobIds() throws JobException {
        try {
            return scheduler.getJobKeys(GroupMatcher.jobGroupEquals(JOB_GROUP)).stream().map(JobKey::getName)
                    .toArray(String[]::new);
        } catch (SchedulerException e) {
            logger.warn("Fail to get job-ids", e);
            throw new JobException("获取job失败");
        }
    }
}
